#include "Graphics/PiccoloVKCommandBuffer.h"

#include <Graphics/PiccoloVKDevice.h>

namespace Piccolo
{
    PiccoloVKCommandPool::PiccoloVKCommandPool(PiccoloVKDevice *device, uint32_t queueFamilyIndex) : mDevice(device)
    {
        VkCommandPoolCreateInfo commandPoolInfo =
        {
            .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
            .pNext = nullptr,
            .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,           // 重置CommandBuffer
            .queueFamilyIndex = queueFamilyIndex
        };
        CALL_VK(vkCreateCommandPool(mDevice->GetLogicDevice(), &commandPoolInfo, nullptr, &mCommandPool));
        LOG_T("Create command pool : {0}", (void*)mCommandPool);
    }

    PiccoloVKCommandPool::~PiccoloVKCommandPool()
    {
        VK_D(CommandPool, mDevice->GetLogicDevice(), mCommandPool);
    }

    std::vector<VkCommandBuffer> PiccoloVKCommandPool::AllocateCommandBuffer(uint32_t count) const
    {
        std::vector<VkCommandBuffer> commandBuffers(count);
        VkCommandBufferAllocateInfo allocateInfo =
        {
            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
            .pNext = nullptr,
            .commandPool = mCommandPool,
            .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
            .commandBufferCount = count
        };
        CALL_VK(vkAllocateCommandBuffers(mDevice->GetLogicDevice(), &allocateInfo, commandBuffers.data()));
        return commandBuffers;
    }

    VkCommandBuffer PiccoloVKCommandPool::AllocateSingleCommandBuffer() const
    {
        auto commandBuffers = AllocateCommandBuffer(1);
        return commandBuffers[0];
    }

    void PiccoloVKCommandPool::BeginCommandBuffer(VkCommandBuffer commandBuffer)
    {
        CALL_VK(vkResetCommandBuffer(commandBuffer, 0));

        VkCommandBufferBeginInfo beginInfo =
        {
            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
            .pNext = nullptr,
            .flags = 0,
            .pInheritanceInfo = nullptr
        };
        CALL_VK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
    }

    void PiccoloVKCommandPool::EndCommandBuffer(VkCommandBuffer commandBuffer)
    {
        CALL_VK(vkEndCommandBuffer(commandBuffer));
    }
}
